package com.kcht.np.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.kcht.np.common.exception.ParameterException;
import com.kcht.np.common.jwt.JwtTokenConverter;
import com.kcht.np.common.jwt.JwtUser;
import com.kcht.np.constant.InitData;
import com.kcht.np.entity.SysPermission;
import com.kcht.np.mapper.SysPermissionMapper;
import com.kcht.np.mapper.SysRoleMapper;
import com.kcht.np.service.SysPermissionService;
import com.kcht.np.vo.permission.PermCanCreateInfo;
import com.kcht.np.vo.permission.PermCanModifyInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Set;

/**
  * <p>
  * 权限 Service 实现类
  * </p>
  *
  * @Package:        com.kcht.np.mp.service.impl
  * @Description:    权限 Service 实现类
  * @Author:         liuqi
  * @CreateDate:     2020/3/31 21:24
 */

@Slf4j
@Service
@DS("kchtnp")
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements SysPermissionService {
    @Autowired
    private SysRoleMapper roleMapper;
    @Autowired
    @Lazy
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private JwtTokenConverter jwtTokenConverter;

    private BoundHashOperations<String, String, JwtUser> tokenStorage() {
        return redisTemplate.boundHashOps(jwtTokenConverter.getTokenHeader());
    }
    @Override
    public Set<SysPermission> findPermissionByUserId(Long uid) {
        return baseMapper.findPermissionByUserId(uid);
    }

    @Override
    public Set<SysPermission> findPermissionByRoleId(Long rid) {
        return baseMapper.findPermissionByRoleId(rid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savePermission(PermCanCreateInfo info) {
        if(baseMapper.findByResource(info.getResources())!=null){
            throw new ParameterException("已存在<"+info.getResources()+">资源");
        }
        if(!InitData.TOP_PER.equals(info.getParentId())
                &&baseMapper.selectById(info.getParentId())==null){
            throw new ParameterException("系统无标识为"+info.getParentId()+"的权限资源");
        }
        SysPermission entity = new SysPermission();
        BeanUtils.copyProperties(info, entity);
        if(entity.getIcon()==null){
            entity.setIcon("");
        }
        if(entity.getDescription()==null){
            entity.setDescription("");
        }
        Set<String> users = roleMapper.usersRefRole(InitData.ROOT_ROLE);
        users.forEach((user)->{tokenStorage().delete(user);});
        baseMapper.insert(entity);
        SysPermission newPer = baseMapper.findByResource(entity.getResources());
        roleMapper.addPermission(newPer.getPid(),InitData.ROOT_ROLE);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePermission(PermCanModifyInfo info) {
        if(InitData.ROOT_PERM > info.getPid()){
            throw new ParameterException("不能修改系统级别的权限资源");
        }
        if(baseMapper.selectById(info.getPid())==null){
            throw new ParameterException("系统无标识为"+info.getParentId()+"的权限资源");
        }
        if(!InitData.TOP_PER.equals(info.getParentId())
                &&baseMapper.selectById(info.getParentId())==null){
            throw new ParameterException("系统无标识为"+info.getPid()+"的权限资源");
        }
        baseMapper.findRefRoleByPid(info.getPid()).forEach((rid)->{
            roleMapper.usersRefRole(rid)
                    .forEach((user)->{tokenStorage().delete(user);});
        });
        SysPermission entity = new SysPermission();
        BeanUtils.copyProperties(info, entity);
        super.updateById(entity);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeById(Serializable id) {
        if(InitData.ROOT_PERM > (Long) id){
            throw new ParameterException("不能删除系统级别的权限资源");
        }
        if(baseMapper.selectById(id)==null){
            throw new ParameterException("系统无标识为"+id+"的权限资源");
        }
        if (baseMapper.countChild((Long)id) > 0) {
            throw new RuntimeException("当前权限下，还有子权限，无法删除！");
        }
        int countRef = baseMapper.countRoleRef((Long) id);
        if ( countRef> 1) {
            throw new RuntimeException("当前权限，还有其他角色在引用，无法删除！");
        }else if(countRef==1){
            roleMapper.deletePermission((Long)id,InitData.ROOT_ROLE);
        }
        return SqlHelper.retBool(baseMapper.deleteById(id));
    }

}
